/****************************************************
	文件：TimerService.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/8/26 11:8:20
	功能：
*****************************************************/

using System;
using System.Collections.Generic;

namespace HTUtility
{
    /// <summary>
    /// 时间单位
    /// </summary>
    public enum TimeUnitType
    {
        /// <summary>
        /// 十分之一微秒（=万分之一毫秒）
        /// </summary>
        Ticks = 0,
        /// <summary>
        /// 毫秒
        /// </summary>
        Milliseconds = 1,
        Seconds = 2,
        Minutes = 3,
        Hours = 4,
        Days = 5,
        NUM = 6,
    }
    public class TimerItem
    {
        public string Name = string.Empty;
        public bool Activate = false;
        public TimeUnitType TimeUnit = TimeUnitType.Milliseconds;
        public TimeSpan Begin = default;
        public TimeSpan End = default;
        /// <summary>
        /// 间隔时间
        /// </summary>
        public float Duration
        {
            get
            {
                if (Activate == false) return 0;
                if (Begin == default || End == default)
                {
                    HTLogger.Error("获取 Duration 失败：尚未赋值 Begin 和 End！");
                    return 0;
                }
                if ((End - Begin).Ticks < 0) return 0.0f;
                switch (TimeUnit)
                {
                    case TimeUnitType.Ticks:
                        return (End - Begin).Ticks;
                    case TimeUnitType.Milliseconds:
                        return (End - Begin).Milliseconds;
                    case TimeUnitType.Seconds:
                        return (End - Begin).Seconds;
                    case TimeUnitType.Minutes:
                        return (End - Begin).Minutes;
                    case TimeUnitType.Hours:
                        return (End - Begin).Hours;
                    case TimeUnitType.Days:
                        return (End - Begin).Days;
                    default:
                        HTLogger.Error("获取 Duration 失败：使用了尚未定义的时间单位！");
                        return 0;
                }
            }
        }
        /// <summary>
        /// 备注信息
        /// </summary>
        public string Info = string.Empty;

        public void Reset()
        {
            Name = string.Empty;
            Activate = false;
            TimeUnit = TimeUnitType.Milliseconds;
            Begin = default;
            End = default;
            Info = string.Empty;
        }
    }
    public class TimerService : HTSingleton<TimerService>
    {
        /// <summary>
        /// 是否开启计时服务
        /// </summary>
        public bool Open { get; set; }

        /// <summary>
        /// TimerItem缓存
        /// </summary>
        private Dictionary<string, TimerItem> mScheduler;
        /// <summary>
        /// TimerItem池
        /// </summary>
        private ClassObjectPool<TimerItem> mTimerItemPool = ClassPoolMgr.Instance.GetOrCreateObjectPool<TimerItem>(20);

        public void Init()
        {
            Open = true;
            mScheduler = new Dictionary<string, TimerItem>();
            HTLogger.Info("TimerService init done.");
        }
        /// <summary>
        /// 订阅计时器
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <param name="info">备注信息</param>
        public void Subscribe(string nameKey, string info = "")
        {
            if (mScheduler.ContainsKey(nameKey))
            {
                HTLogger.Error("重复注册 TimerService ，name：" + nameKey);
                return;
            }
            TimerItem item = mTimerItemPool.Spawn(true);
            item.Name = nameKey;
            item.Activate = true;
            item.Info = info;
            mScheduler.Add(nameKey, item);
        }
        /// <summary>
        /// 注销计时器
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <returns></returns>
        public bool Unsubscribe(string nameKey)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item))
            {
                if (item != null)
                {
                    item.Reset();
                    mTimerItemPool.Recycle(item);
                }
                mScheduler.Remove(nameKey);
                return true;
            }
            else
            {
                HTLogger.Error("注销 TimerService 失败，缓存中不存在 " + nameKey + " ，检查是否重复注销");
                return false;
            }
        }
        /// <summary>
        /// 搜索TimerItem
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <returns></returns>
        public TimerItem FindTimerItem(string nameKey)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return null;
            }
            return item;
        }
        /// <summary>
        /// 设置TimerItem激活状态
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <param name="activate">激活状态</param>
        public void SetTimerActivate(string nameKey, bool activate)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return;
            }
            item.Activate = activate;
        }
        /// <summary>
        /// 设置开始计时
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        public void Begin(string nameKey)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return;
            }
            item.Begin = DateTime.Now.TimeOfDay;
        }
        /// <summary>
        /// 设置结束计时
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        public void End(string nameKey)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return;
            }
            item.End = DateTime.Now.TimeOfDay;
        }
        /// <summary>
        /// 获取计时时间
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <param name="timeUnit">计时单位</param>
        /// <returns></returns>
        public float GetTotalTime(string nameKey, TimeUnitType timeUnit = TimeUnitType.Milliseconds)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return 0.0f;
            }
            item.TimeUnit = timeUnit;
            return item.Duration;
        }
        /// <summary>
        /// 打印、获取计时器备注信息
        /// </summary>
        /// <param name="nameKey">计时器名</param>
        /// <param name="logMsg">是否打印计时器备注信息</param>
        /// <returns></returns>
        public string LogInfo(string nameKey, bool logMsg = true)
        {
            TimerItem item = null;
            if (mScheduler.TryGetValue(nameKey, out item) == false)
            {
                HTLogger.Warning("TimerService 中未注册过：" + nameKey);
                return "";
            }
            if (logMsg)
            {
                HTLogger.Info(item.Info);
            }
            return item.Info;
        }
    }
}
